package cn.liontalk.ProxyPattern.dynamics;

import cn.liontalk.ProxyPattern.pattern3.ChanelFactory;
import cn.liontalk.ProxyPattern.pattern3.SellPerfume;

import java.lang.reflect.Proxy;

public class XiaoMing {

    public static void main(String[] args) {

        /**
         * （1）JDK 动态代理的使用方法
         * 代理工厂需要实现 InvocationHandler接口，调用代理方法时会转向执行invoke()方法
         * 生成代理对象需要使用Proxy对象中的newProxyInstance()方法，返回对象可强转成传入的其中一个接口，
         *  然后调用接口方法即可实现代理
         * （2）JDK 动态代理的特点
         * 目标对象强制需要实现一个接口，否则无法使用 JDK 动态代理
         *
         */

        /**
         * ClassLoader loader：加载动态代理类的类加载器
         * Class<?>[] interfaces：代理类实现的接口，可以传入多个接口
         * InvocationHandler h：指定代理类的「调用处理程序」，即调用接口中的方法时，会找到该代理工厂h，执行invoke()方法
         */
        ChanelFactory chanelFactory = new ChanelFactory();
        SellProxyFactory sellProxyFactory = new SellProxyFactory(chanelFactory);
        SellPerfume sellPerfume =  (SellPerfume) Proxy.newProxyInstance(
               chanelFactory.getClass().getClassLoader(), chanelFactory.getClass().getInterfaces(),sellProxyFactory);
        sellPerfume.sellPerfume(19);

        System.out.println("================================================");
        //实例化一个红酒销售商
        RedWineFactory redWineFactory = new RedWineFactory();
        // 实例化代理工厂，传入红酒销售商引用控制对其的访问
        SellProxyFactory sellProxyFactory1 = new SellProxyFactory(redWineFactory);
        // 实例化代理对象，该对象可以代理售卖红酒
        SellWine sellPerfume2 =  (SellWine) Proxy.newProxyInstance(
                redWineFactory.getClass().getClassLoader(), redWineFactory.getClass().getInterfaces(),sellProxyFactory1);
        // 代理售卖红酒
        sellPerfume2.sellWine(192);
    }
}
